package name.luojun.DBhelper.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
public class SqlExcutor extends NamedParameterJdbcDaoSupport {
	protected static Logger log = Logger.getLogger(SqlExcutor.class.getName());
	private String[] path;
	private String rule;
	private boolean stoponerror = true;
	@Override
	protected void initDao() {
		try {
			super.initDao();
		} catch (Exception e) {
		}
		ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
		for (String pathstr : path) {
			try {
				Resource[] source = resourceLoader.getResources(pathstr);
				for (Resource r : source) {
					execute(r);
					if ("once".equalsIgnoreCase(rule)) {
						File file = r.getFile();
						file.delete();
					}
				}
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
	}
	public String getRule() {
		return rule;
	}
	public void setRule(String rule) {
		this.rule = rule.trim();
	}
	private void execute(Resource r) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(r.getInputStream(), "UTF-8"));
		this.runScript(reader);
		reader.close();
	}
	public String[] getPath() {
		return path;
	}
	public void setPath(String[] path) {
		this.path = path;
	}
	public boolean getStoponerror() {
		return stoponerror;
	}
	public void setStoponerror(boolean stoponerror) {
		this.stoponerror = stoponerror;
	}
	private void runScript(Reader reader) throws SQLException {
		Connection conn = this.getConnection();
		try {
			SqlExcutor.runScript(conn, reader, stoponerror);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			this.releaseConnection(conn);
		}
	}
	public static void runScript(Connection conn, Reader reader, boolean stoponerror) throws SQLException {
		LineNumberReader lineReader = new LineNumberReader(reader);
		String line = null;
		StringBuffer command = new StringBuffer();
		conn.setAutoCommit(false);
		boolean inSQuot = false;
		boolean inDQuot = false;
		boolean annotation = false;
		try {
			while ((line = lineReader.readLine()) != null) {
				String trimmedLine = line.trim();
				if (trimmedLine.length() >= 1 && !trimmedLine.startsWith("//") && !trimmedLine.startsWith("--")) {
					for (int i = 0; i < trimmedLine.length(); i++) {
						char chr = trimmedLine.charAt(i);
						if (chr == '"' && !inDQuot && !inSQuot) {
							inDQuot = true;
						} else if (chr == '\'' && !inDQuot && !inSQuot) {
							inSQuot = true;
						} else if (chr == '"' && inDQuot) {
							inDQuot = false;
						} else if (chr == '\'' && inSQuot) {
							inSQuot = false;
						}
						if (!inDQuot && !inSQuot) {
							if (i < trimmedLine.length() - 1) {
								if (chr == '-' && trimmedLine.charAt(i + 1) == '-') {
									break;
								}
								if (chr == '/' && trimmedLine.charAt(i + 1) == '*' && !annotation) {
									annotation = true;
									if (command.length() > 0)
										command.append(" ");
									continue;
								}
								if (chr == '*' && trimmedLine.charAt(i + 1) == '/' && annotation) {
									annotation = false;
									i++;
									continue;
								}
							}
							if (chr == ';') {
								Statement statement = conn.createStatement();
								if (stoponerror) {
									String execution = command.toString();
									log.debug(execution);
									statement.execute(execution);
								} else {
									try {
										String execution = command.toString();
										log.debug(execution);
										statement.execute(execution);
									} catch (Exception e) {
										log.error(e.getMessage());
									}
								}
								command.setLength(0);
								continue;
							}
						}
						if (!annotation)
							command.append(chr);
					}
					if (command.length() > 0)
						command.append(" ");
				}
			}
			if (command.length() != 0) {
				Statement statement = conn.createStatement();
				if (stoponerror) {
					String execution = command.toString();
					log.debug(execution);
					statement.execute(execution);
				} else {
					try {
						String execution = command.toString();
						log.debug(execution);
						statement.execute(execution);
					} catch (Exception e) {
						log.error(e.getMessage());
					}
				}
				command.setLength(0);
			}
			conn.commit();
		} catch (Exception e) {
			e.printStackTrace();
			conn.rollback();
		}
	}
}
